package gscore

import (
	"context"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/spf13/cobra"
)

type BaseServer struct {
	serverName string
	waitGroup  sync.WaitGroup
	osSignal   chan os.Signal
	IsGraceful bool
	Ctx        context.Context
	Cancel     context.CancelFunc
	WorkPath   string
	cobraCmd   *cobra.Command
}

func (x *BaseServer) GetCobraCmd() *cobra.Command {
	return x.cobraCmd
}

func (x *BaseServer) SetCobraCmd(cobraCmd *cobra.Command) {
	x.cobraCmd = cobraCmd
}

func (x *BaseServer) GetServerName() string {
	return x.serverName
}

func (x *BaseServer) SetServerName(serverName string) {
	x.serverName = serverName
}

func (x *BaseServer) AddGracefulTask(task GracefulTask) {
	x.waitGroup.Add(1)
	go func() {
		defer func() {
			x.waitGroup.Done()
		}()
		task(x.Ctx)
	}()
}

func (x *BaseServer) GracefulExit() {
	// 等待所有任务执行完毕
	go x.waitSingle()
	x.waitGroup.Wait()
	time.Sleep(time.Second)
	os.Exit(0)
}

// 监听外部退出信号
func (x *BaseServer) waitSingle() {
	x.osSignal = make(chan os.Signal)
	signal.Notify(x.osSignal, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
	<-x.osSignal
	// 通知context退出事件
	x.Cancel()
}

// 主动关闭退出
func (x *BaseServer) Shutdown() {
	x.osSignal <- syscall.SIGQUIT
}

// 捕获退出信号
func (x *BaseServer) Done() <-chan struct{} {
	return x.Ctx.Done()
}
